package ezXpns;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import org.apache.commons.lang3.tuple.ImmutablePair;
import org.apache.commons.lang3.tuple.Pair;

/**
 * 
 * @author A0086894H 
 * This class imports BudgetChange data from a CSV file
 * 
 */

//@author A0086894H
public class ImportCsv {
	/**
	 * This method imports a CSV for expenses
	 * 
	 * @param sFileName
	 *            : path of file to be imported
	 * @throws ParseException
	 */
	public static Vector<Pair<UUID, BudgetChange>> importExpense(String sFileName) throws IOException,
			ImportFileMismatch, ParseException {
		// list to return
		Vector<Pair<UUID, BudgetChange>> expenseList = new Vector<Pair<UUID, BudgetChange>>();

		// read in CSV file
		File expenseCsv = new File(sFileName);
		BufferedReader bufRdr = new BufferedReader(new FileReader(expenseCsv));
		String line = null; // String of each line read from file

		// scans each line of text file
		int lineNum = 1; // line number in CSV file
		while ((line = bufRdr.readLine()) != null) {
			StringTokenizer lineTokens = new StringTokenizer(line, ","); // breaks
																			// each
																			// line
																			// into
																			// tokens
																			// separated
																			// by
																			// ","

			// get next token
			if (lineNum == 1) {
				String token = lineTokens.nextToken();
				String user = token;
				// TODO read in user
			}

			// throws exception if CSV file is not for Expense
			else if (lineNum == 3) {
				String token = lineTokens.nextToken();
				if (!token.equals("EXPENSE ONLY")) {
					bufRdr.close();
					throw new ImportFileMismatch(token);
				}
			}

			// stores into list
			else if (lineNum >= 5) { // entries are displayed from line 5
										// onwards

				UUID uuid = UUID.fromString(lineTokens.nextToken());

				String dateString = lineTokens.nextToken();
				Date date;
				date = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy", Locale.ENGLISH).parse(dateString);

				String name = lineTokens.nextToken();
				float amount = Float.parseFloat(lineTokens.nextToken());
				String payment = lineTokens.nextToken();
				String tags = new String();
				if (lineTokens.hasMoreTokens()) { // tags is optional field
					tags = lineTokens.nextToken();
				}

				// creates an expense entry from values read
				BudgetChange expenseEntry = new BudgetChange();
				expenseEntry.setDate(date);
				expenseEntry.setName(name);
				expenseEntry.setAmount(amount);
				expenseEntry.setType(payment);
				expenseEntry.setTagsFromString(tags);

				// adds new pair to list
				expenseList.add(new ImmutablePair<UUID, BudgetChange>(uuid, expenseEntry));
			}
			lineNum++;
		}
		
		bufRdr.close();
		return expenseList;
	}

	/**
	 * This method imports a CSV for income
	 * 
	 * @param sFileName
	 *            : path of file to be imported
	 * @throws ParseException
	 */
	public static Vector<Pair<UUID, BudgetChange>> importIncome(String sFileName) throws IOException,
			ImportFileMismatch, ParseException {

		Vector<Pair<UUID, BudgetChange>> incomeList = new Vector<Pair<UUID, BudgetChange>>();

		// read in CSV file
		File incomeCsv = new File(sFileName);

		System.out.println(incomeCsv.getAbsolutePath());

		BufferedReader bufRdr = new BufferedReader(new FileReader(incomeCsv));
		String line = null; // String of each line read from file

		// scans each line of text file
		int lineNum = 1; // line number in CSV file
		while ((line = bufRdr.readLine()) != null) {
			StringTokenizer lineTokens = new StringTokenizer(line, ","); // breaks
																			// each
																			// line
																			// into
																			// tokens
																			// separated
																			// by
																			// ","

			// get next token
			if (lineNum == 1) {
				String token = lineTokens.nextToken();
				String user = token;
				// TODO read in user
			}

			// throws exception if CSV file is not for Income
			else if (lineNum == 3) {
				String token = lineTokens.nextToken();
				if (!token.equals("INCOME ONLY")) {
					bufRdr.close();
					throw new ImportFileMismatch(token);
				}
			}

			// stores into list
			else if (lineNum >= 5) { // entries are displayed from line 5
										// onwards

				UUID uuid = UUID.fromString(lineTokens.nextToken());

				String dateString = lineTokens.nextToken();
				Date date;
				date = new SimpleDateFormat("E MMM dd HH:mm:ss z yyyy", Locale.ENGLISH).parse(dateString);

				String name = lineTokens.nextToken();
				float amount = Float.parseFloat(lineTokens.nextToken());
				String frequency = lineTokens.nextToken();
				String tags = new String();
				if (lineTokens.hasMoreTokens()) { // tags is optional field
					tags = lineTokens.nextToken();
				}

				// creates an income entry from values read
				BudgetChange incomeEntry = new BudgetChange();
				incomeEntry.setDate(date);
				incomeEntry.setName(name);
				incomeEntry.setAmount(amount);
				incomeEntry.setType(frequency);
				incomeEntry.setTagsFromString(tags);

				// adds new pair to list
				incomeList.add(new ImmutablePair<UUID, BudgetChange>(uuid, incomeEntry));
			}
			lineNum++;
		}
		bufRdr.close();
		return incomeList;
	}

	// Exception class for import
	public static class ImportFileMismatch extends Exception {

		public ImportFileMismatch(String name) {
			this.name = name;
		}

		public String toString() {
			return "CSV type to import can only be for" + " " + name;
		}

		private static final long serialVersionUID = 1L;
		private String name;
	}
}